package edu.vt.cbil.ui;

import com.jidesoft.swing.CheckBoxList;
import edu.vt.cbil.core.Controller;
import edu.vt.cbil.dataset.AnnotationDataSet;
import edu.vt.cbil.util.BioLogger;
import edu.vt.cbil.util.ConfigObject;

import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Map;

/**
 * Created by Justin on 2015/4/10.
 */
public class BACOMGUI {
    public JFrame m_form;
    //    private BioCollection m_data;
    public ConfigObject p_config;
    public ArrayList<String> allItems;
    private AnnotationDataSet annot;
    private JPanel panel1;
    private JTabbedPane tabbedPane1;
    private JTextField tfAnnotation;
    private JButton bnAnnotation;
    private JTextField tfCDF;
    private JTextField tfResult;
    private JTextField tfSample;
    private JButton bnCDF;
    private JButton bnResult;
    private JButton bnSample;
    private JSpinner spSmoothWidth;
    private JSpinner spRouWinSize;
    private JTextField tfPValue;
    private JSpinner spSegLength;
    private JSpinner spSegStep;
    private JTextField tfCombineFactor;
    private JTextField tfAlphaPosition;
    private JCheckBox rouChartCheckBox;
    private JCheckBox probesetsChartCheckBox;
    private JButton bnApply;
    private JPanel samplePanel;
    private JButton runButton;
    private JButton samplesButton;
    private JButton deleteSampleButton;
    private JButton saveButton;
    private JScrollPane scrollPane1;
    private CheckBoxList sampleList;
    private boolean alreadyReadAnnoAnnotation;

    public BACOMGUI(ConfigObject pc) {
        p_config = pc;
        alreadyReadAnnoAnnotation = false;

        bnAnnotation.addActionListener(new ActionListener() {
            /**
             * Invoked when an action occurs.
             *
             * @param e
             */
            @Override
            public void actionPerformed(ActionEvent e) {
                JFileChooser chooser = new JFileChooser();
                chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
                FileNameExtensionFilter filter = new FileNameExtensionFilter(
                        "SQLite File (*.db)", "db");
                chooser.setFileFilter(filter);
                chooser.setCurrentDirectory(new File(p_config.getAnnotationFile()));

                int returnVal = chooser.showOpenDialog(m_form);
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    String selectPath = chooser.getSelectedFile().getPath();
                    tfAnnotation.setText(selectPath);
                    p_config.setAnnotationFile(selectPath);
                }

            }
        });

        bnCDF.addActionListener(new ActionListener() {
            /**
             * Invoked when an action occurs.
             *
             * @param e
             */
            @Override
            public void actionPerformed(ActionEvent e) {
                JFileChooser chooser = new JFileChooser();
                chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
                FileNameExtensionFilter filter = new FileNameExtensionFilter(
                        "CDF File (*.cdf)", "cdf");
                chooser.setFileFilter(filter);
                chooser.setCurrentDirectory(new File(p_config.getCDFFile()));

                int returnVal = chooser.showOpenDialog(m_form);
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    String selectPath = chooser.getSelectedFile().getPath();
                    tfCDF.setText(selectPath);
                    p_config.setCDFFile(selectPath);
                }

            }
        });

        bnResult.addActionListener(new ActionListener() {
            /**
             * Invoked when an action occurs.
             *
             * @param e
             */
            @Override
            public void actionPerformed(ActionEvent e) {
                JFileChooser chooser = new JFileChooser();
                chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                chooser.setCurrentDirectory(new File(p_config.getDBPath()).getParentFile());

                int returnVal = chooser.showOpenDialog(m_form);
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    String selectPath = chooser.getSelectedFile().getPath();
                    tfResult.setText(selectPath);
                    p_config.setDBPath(selectPath);
                }

            }
        });

        bnSample.addActionListener(new ActionListener() {
            /**
             * Invoked when an action occurs.
             *
             * @param e
             */
            @Override
            public void actionPerformed(ActionEvent e) {
                JFileChooser chooser = new JFileChooser();
                chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
                chooser.setCurrentDirectory(new File(p_config.getSamplePath()).getParentFile());

                int returnVal = chooser.showOpenDialog(m_form);
                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    String selectPath = chooser.getSelectedFile().getPath();
                    tfSample.setText(selectPath);
                    p_config.setSamplePath(selectPath);
                }

            }
        });

        bnApply.addActionListener(new ActionListener() {
            /**
             * Invoked when an action occurs.
             *
             * @param e
             */
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    p_config.params.smoothingCopyNumber_Width = (Integer) spSmoothWidth.getValue();
                    p_config.params.rou_WindowsSize = (Integer) spRouWinSize.getValue();
                    p_config.params.PVALUE_THRESH = Double.valueOf(tfPValue.getText());
                    p_config.params.MIN_SEG_LENGTH = (Integer) spSegLength.getValue();
                    p_config.params.MIN_SEG_STEP = (Integer) spSegStep.getValue();
                    p_config.params.COMBINE_FACTOR = Double.valueOf(tfCombineFactor.getText());
                    p_config.params.ALPHA_POSITION = Double.valueOf(tfAlphaPosition.getText());
                    p_config.params.enable_rou_chart = rouChartCheckBox.isSelected();
                    p_config.params.enable_probeset_chart = probesetsChartCheckBox.isSelected();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });


        sampleList = new CheckBoxList();
        scrollPane1 = new JScrollPane(sampleList);
        samplePanel.add(scrollPane1);

        runButton.addActionListener(new ActionListener() {
            /**
             * Invoked when an action occurs.
             *
             * @param e
             */
            @Override
            public void actionPerformed(ActionEvent e) {
                refreshSelectedSampleIDs();
                if (!alreadyReadAnnoAnnotation) {
                    annot = new AnnotationDataSet(p_config.getAnnotationFile());

                    Date date = new Date();
                    SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd_HHmmss");
                    String filename = String.format("Result_%s.log", df.format(date));
                    BioLogger log = new BioLogger(p_config.getDBPath(), filename);
                    date = null;
                    df = null;

                    alreadyReadAnnoAnnotation = true;

                    Controller myCore = new Controller(p_config, annot);
                    myCore.run(true);
                } else {
                    Controller myCore = new Controller(p_config, annot);
                    myCore.run(false);
                }

                new JOptionPane().showMessageDialog(null, "Completed!");
            }
        });
        samplesButton.addActionListener(new ActionListener() {
            /**
             * Invoked when an action occurs.
             *
             * @param e
             */
            @Override
            public void actionPerformed(ActionEvent e) {
                showAddNewSamplePairDialog();
            }
        });
        deleteSampleButton.addActionListener(new ActionListener() {
            /**
             * Invoked when an action occurs.
             *
             * @param e
             */
            @Override
            public void actionPerformed(ActionEvent e) {
                deleteSamplePair();
            }
        });
        saveButton.addActionListener(new ActionListener() {
            /**
             * Invoked when an action occurs.
             *
             * @param e
             */
            @Override
            public void actionPerformed(ActionEvent e) {
                for (int i : sampleList.getCheckBoxListSelectedIndices()) {
                    p_config.TestingSampleIDs.add(allItems.get(i));
                }

                p_config.writeConfig("settings.xml");
            }
        });
    }

    private void showAddNewSamplePairDialog() {
        SampleEditForm seForm = new SampleEditForm(this);
        seForm.setSize(640, 200);
        seForm.setSamplePath(p_config.getSamplePath());
        seForm.setVisible(true);
    }

    public void addNewSamplePair(String id, String normalFile, String tumorFile) {
        p_config.addNewSamplePair(id, normalFile, tumorFile);
        refreshSampleList();
    }


    public void deleteSamplePair() {
        for (int i : sampleList.getCheckBoxListSelectedIndices()) {
            p_config.deleteSamplePair(allItems.get(i));
        }

        refreshSampleList();
    }


    public void refreshSampleList() {
        allItems = new ArrayList<String>();
        DefaultListModel dlm = new DefaultListModel();
        for (Map.Entry<String, String[]> sample : p_config.SampleFiles.entrySet()) {
            String normal = sample.getValue()[0];
            String tumor = sample.getValue()[1];
//            normal = normal.substring(normal.lastIndexOf(File.separator) + 1, normal.length() - 4);
//            tumor = tumor.substring(tumor.lastIndexOf(File.separator) + 1, tumor.length() - 4);
            String str = String.format("%s->[N]:%s;[T]:%s", sample.getKey(), normal, tumor);
            dlm.addElement(str);
            allItems.add(sample.getKey());
        }
        sampleList.setModel(dlm);
        int n[] = new int[p_config.TestingSampleIDs.size()];
        int i = 0;
        for (String sampleId : p_config.TestingSampleIDs) {
            n[i] = allItems.indexOf(sampleId);
            i++;
        }
        sampleList.setCheckBoxListSelectedIndices(n);

    }

    private void refreshSelectedSampleIDs() {
        p_config.TestingSampleIDs.clear();
        for (int i : sampleList.getCheckBoxListSelectedIndices()) {
            p_config.TestingSampleIDs.add(allItems.get(i));
        }
    }


    public void createForm() {
        m_form = new JFrame("BACOMGUI");
        m_form.setContentPane(panel1);
        m_form.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        m_form.pack();

        m_form.setSize(640, 500);
        m_form.setVisible(true);

        tfPValue.setHorizontalAlignment(JTextField.RIGHT);
        tfPValue.setHorizontalAlignment(JTextField.RIGHT);
        tfCombineFactor.setHorizontalAlignment(JTextField.RIGHT);
        tfAlphaPosition.setHorizontalAlignment(JTextField.RIGHT);
//        spSmoothWidth

        tfAnnotation.setText(p_config.getAnnotationFile());
        tfCDF.setText(p_config.getCDFFile());
        tfResult.setText(p_config.getDBPath());
        tfSample.setText(p_config.getSamplePath());
        spSmoothWidth.setValue(p_config.params.smoothingCopyNumber_Width);
        spRouWinSize.setValue(p_config.params.rou_WindowsSize);
        tfPValue.setText(Double.toString(p_config.params.PVALUE_THRESH));
        spSegLength.setValue(p_config.params.MIN_SEG_LENGTH);
        spSegStep.setValue(p_config.params.MIN_SEG_STEP);
        tfCombineFactor.setText(Double.toString(p_config.params.COMBINE_FACTOR));
        tfAlphaPosition.setText(Double.toString(p_config.params.ALPHA_POSITION));
        rouChartCheckBox.setSelected(p_config.params.enable_rou_chart);
        probesetsChartCheckBox.setSelected(p_config.params.enable_probeset_chart);

        refreshSampleList();
    }
}
